#ifndef PORTMONITOR_H
#define PORTMONITOR_H

#include <QObject>
#include <QSerialPortInfo>
#include <QMutex>

class OnMonitorListener {
public:
    virtual ~OnMonitorListener();
    virtual void onPortArrival(QString port, QSerialPortInfo& info) = 0;
    virtual void onPortRemoved(QString port, QSerialPortInfo& info) = 0;
};

struct PortFilterInfo {
    int pid;
    int vid;

    PortFilterInfo(int pid, int vid);
    bool match(int pid, int vid);
    bool match(QSerialPortInfo& info);
};

class PortMonitor : public QObject
{
    Q_OBJECT
protected:
    QList<PortFilterInfo> mFilters;
    QList<QSerialPortInfo> mPortList;
    OnMonitorListener* mpListener;
    QMutex mLock;

protected:
    explicit PortMonitor(QList<PortFilterInfo>& filters, QObject *parent = nullptr);

public:
    virtual ~PortMonitor();

    static PortMonitor* create(QObject* parent = nullptr);
    static PortMonitor* create(int pid, int vid, QObject* parent = nullptr);
    static PortMonitor* create(PortFilterInfo filter, QObject* parent = nullptr);
    static PortMonitor* create(QList<PortFilterInfo> filters, QObject* parent = nullptr);

    virtual void startMonitor(void* win, OnMonitorListener* pListener);
    virtual void stopMonitor();

    void loadPorts();
    QList<QSerialPortInfo> getPorts();
    QSerialPortInfo getPort(QString name);

    inline bool isMonitorPort(QSerialPortInfo& info);

    void notifyPortArrival(QString name);
    void notifyPortRemoved(QString name);

protected:
    virtual void onStartMonitor(void* win) = 0;
    virtual void onStopMonitor() = 0;
};

#endif // PORTMONITOR_H
